#ifndef BOARD_H
#define BOARD_H

#include "common.h"
#include "effect.h"
#include "side.h"

const int CounterMax = 4096;

//------------------------------------------------------------
struct board_t {

  // variables

  int turn;

  int square[256];
  int hand[2][8];

  int king[2];
  int pawn[2][16];

  uint64 square64;
  uint32 hand32[2];

  effect_t effect[2][256];

  int undo[CounterMax];
  int counter;

  // methods

  void clear();
  void build();

  void init(Handicap handi);

  void copy_to(board_t &that);
  bool is_consistent();

  void print_ef();

  int skip(int from, int dir) {
    int to;
    for (to=from+dir; square[to]==0; to+=dir)
      continue;
    return to;
  }
};

// 0x 0 0 0 0 0 0 0 0
// **-Fu-KyKeGiKiKaHi => bit offset = (k-HI) * 4
#define H32(k) (1<<((HI-(k))<<2))

//------------------------------------------------------------
template<Color C>
class Board : public SideInfo<C>
{
private:
  board_t &b;
public:
  explicit Board(board_t& b1) : b(b1) {}
  int& _turn() { return b.turn; }
  int& _square(int pos) { return b.square[pos]; }
  int& _hand(int c,int k) { return b.hand[c][k]; }
  int& _my_hand(int k) { return b.hand[Me][k]; }
  int& _opp_hand(int k) { return b.hand[Opp][k]; }
  int& _king(int c) { return b.king[c]; }
  int& _pawn(int c,int x) { return b.pawn[c][x]; }

  void effect_update();

  void put_piece(int pos,int k);
  void unput_piece(int pos);

  void move_do(int move);
  void move_undo();
};

#define turn() (this->_turn())
#define square(pos) (this->_square(pos))
#define hand(c,k) (this->_hand(c,k))
#define my_hand(k) (this->_my_hand(k))
#define opp_hand(k) (this->_opp_hand(k))
#define king(c) (this->_king(c))
#define pawn(c,x) (this->_pawn(c,x))

//------------------------------------------------------------
extern void board_init();

//------------------------------------------------------------

#endif // BOARD_H
